// $(document).ready(function () {
//
//     // 输入框格式化
//     let maskOption = {
//         translation: {
//             'Z': {
//                 pattern: /./, optional: true
//             }
//         }
//     };
//     $input_case_name.mask('Z'.repeat(200), maskOption);  // 限制长度为200
//     $input_case_description.mask('Z'.repeat(200), maskOption);
//
//     // 渲染文本编辑器
//     // 请求头
//     ace_request_header_editor = ace.edit("div-ace-request-header");
//     ace_request_header_editor.setReadOnly(true);
//     ace_request_header_editor.setTheme("ace/theme/eclipse");
//     ace_request_header_editor.session.setMode("ace/mode/json");
//     // 请求体
//     ace_request_body_editor = ace.edit("div-ace-request-body");
//     ace_request_body_editor.setReadOnly(true);
//     ace_request_body_editor.setTheme("ace/theme/eclipse");
//     ace_request_body_editor.session.setMode("ace/mode/json");
//     // 应答头
//     ace_response_header_editor = ace.edit("div-ace-response-header");
//     ace_response_header_editor.setReadOnly(true);
//     ace_response_header_editor.setTheme("ace/theme/eclipse");
//     ace_response_header_editor.session.setMode("ace/mode/json");
//     // 应答体
//     ace_response_body_editor = ace.edit("div-ace-response-body");
//     ace_response_body_editor.setReadOnly(true);
//     ace_response_body_editor.setTheme("ace/theme/eclipse");
//     ace_response_body_editor.session.setMode("ace/mode/html");
//     // 预处理脚本
//     ace_preprocessor_script_editor = ace.edit("div-ace-preprocessor-script");
//     ace_preprocessor_script_editor.setTheme("ace/theme/eclipse");
//     ace_preprocessor_script_editor.session.setMode("ace/mode/python");
//     // 后处理脚本
//     ace_postprocessor_script_editor = ace.edit("div-ace-postprocessor-script");
//     ace_postprocessor_script_editor.setTheme("ace/theme/eclipse");
//     ace_postprocessor_script_editor.session.setMode("ace/mode/python");
//     // 日志
//     ace_log_editor = ace.edit("div-ace-log");
//     ace_log_editor.setTheme("ace/theme/eclipse");
//
//     // 事件绑定
//     $(document).on('keydown', documentSaveCase);
//     $input_case_name.on("change keyup", updateCaseName);
//     $select_method.on("change", updateCaseMethod);  // 有些case没有select_method元素, jquery会忽略对不存在元素的操作, 且不会报错
//     $btn_case_save.bind("click", saveCase);
//     $btn_case_send.bind("click", sendCase);
//     $btn_save_response.bind("click", saveResponse);
//     $radio_beautify_request_code.bind("click", beautifyRequestCode);
//     $radio_default_request_code.bind("click", defaultRequestCode);
//     $radio_beautify_response_code.bind("click", beautifyResponseCode);
//     $radio_default_response_code.bind("click", defaultResponseCode);
//     $button_ace_preprocessor_get_variable.bind("click", {'editor': ace_preprocessor_script_editor, 'text': 'temp = vars.get(\'变量名\')'}, scriptInsertText);
//     $button_ace_preprocessor_set_variable.bind("click", {'editor': ace_preprocessor_script_editor, 'text': 'vars[\'变量名\'] = 值'}, scriptInsertText);
//     $button_ace_postprocessor_get_variable.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'temp = vars.get(\'变量名\')'}, scriptInsertText);
//     $button_ace_postprocessor_set_variable.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'vars[\'变量名\'] = 值'}, scriptInsertText);
//     $button_ace_postprocessor_get_request_headers.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'temp = request_headers'}, scriptInsertText);
//     $button_ace_postprocessor_get_request_body.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'temp = request_body'}, scriptInsertText);
//     $button_ace_postprocessor_get_response_headers.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'temp = response_headers'}, scriptInsertText);
//     $button_ace_postprocessor_get_response_body.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'temp = response_body'}, scriptInsertText);
//     $button_ace_postprocessor_get_set_assert.bind("click", {'editor': ace_postprocessor_script_editor, 'text': 'if 1 != 0:\n    failure = True\n    failure_message = \'后处理断言失败\''}, scriptInsertText);
//
// });
//
// let case_id = $("#input-case-id").val();
// let ace_request_header_editor = null;       // 请求头格式化编辑器
// let ace_request_body_editor = null;         // 请求体格式化编辑器
// let ace_response_header_editor = null;      // 应答头格式化编辑器
// let ace_response_body_editor = null;        // 应答体格式化编辑器
// let ace_preprocessor_script_editor = null;  // 预处理脚本格式化编辑器
// let ace_postprocessor_script_editor = null; // 后处理脚本格式化编辑器
// let ace_log_editor = null;                  // 日志展示
// let table_expectation = null;               // 期望数据表格
// let request_header_default_data = '';       // 请求头默认数据
// let request_body_defalut_data = '';         // 请求体默认数据
// let response_header_default_data = '';      // 应答头默认数据
// let response_body_default_data = '';        // 应答体默认数据
// // 界面元素
// // top页面
// let wtd = window.top.document;
// let $wtd_div_case_name =  $('.case-name[data-case-id='+ case_id +']', wtd);
// let $wtd_div_case_method =  $('.case-method[data-case-id='+ case_id +']', wtd);
// // 案例页面
// let $input_case_type = $('#input-case-type');
// let $input_case_name = $("#input-case-name");
// let $input_case_description = $("#input-case-description");
// let $select_method = $("#select-method");
// let $btn_case_delete = $("#btn-case-delete");
// let $btn_case_save = $("#btn-case-save");
// let $btn_case_send = $("#btn-case-send");
// let $btn_case_send_spinner = $("#btn-case-send-spinner");
// let $div_spinner = $("#div-spinner");
//
// let $pills_expectation_tab = $("#pills-expectation-tab");
// let $pills_postprocessor_script_tab = $("#pills-postprocessor-script-tab");
// let $div_table_expectation_spinner = $('#div-table-expectation-spinner');
// let $btn_save_response = $("#btn-save-response");
// let $radio_expectation_logic_and = $("#radio-expectation-logic-and");
// let $radio_expectation_logic_or = $("#radio-expectation-logic-or");
// let $radio_default_request_code = $("#radio-default-request-code");
// let $radio_beautify_request_code = $("#radio-beautify-request-code");
// let $radio_default_response_code = $("#radio-default-response-code");
// let $radio_beautify_response_code = $("#radio-beautify-response-code");
// let $div_postprocessor_result_card = $("#div-postprocessor-result-card");
// let $badge_postprocessor_result_success = $("#badge-postprocessor-result-success");
// let $badge_postprocessor_result_failure = $("#badge-postprocessor-result-failure");
// let $p_postprocessor_result_card_text = $("#p-postprocessor-result-card-text");
// let $div_assert_result_success_hint = $("#div-assert-result-success-hint");
// let $div_expectation_result_failure_hint = $("#div-expectation-result-failure-hint");
// let $div_expectation_not_set_hint = $("#div-expectation-not-set-hint");
// let $div_postprocessor_result_failure_hint = $("#div-postprocessor-result-failure-hint");
// let $button_ace_preprocessor_set_variable = $("#button-ace-preprocessor-set-variable");
// let $button_ace_preprocessor_get_variable = $("#button-ace-preprocessor-get-variable");
// let $button_ace_postprocessor_get_variable = $("#button-ace-postprocessor-get-variable");
// let $button_ace_postprocessor_set_variable= $("#button-ace-postprocessor-set-variable");
// let $button_ace_postprocessor_get_request_headers = $("#button-ace-postprocessor-get-request-headers");
// let $button_ace_postprocessor_get_request_body = $("#button-ace-postprocessor-get-request-body");
// let $button_ace_postprocessor_get_response_headers = $("#button-ace-postprocessor-get-response-headers");
// let $button_ace_postprocessor_get_response_body = $("#button-ace-postprocessor-get-response-body");
// let $button_ace_postprocessor_get_set_assert = $("#button-ace-postprocessor-set-assert");
//
//
//
// // 渲染期望表格
// function renderExpectationTable() {
//     const container_table_expectation = document.getElementById('table-expectation');
//     const option_table_expectation = {
//         data: data_expectations,
//         rowHeaders: true,
//         // colHeaders: true,
//         licenseKey: 'non-commercial-and-evaluation',
//         // 表格宽度
//         // width: '95vw',  // 不指定宽度使其自适应容器
//         // 拉伸方式
//         stretchH: 'all',
//         // tab键自动换行切换
//         autoWrapRow: true,
//         height: '65vh',
//         // 最大行数
//         maxRows: 99,
//         // 允许手工移动行或列
//         manualRowResize: true,
//         manualColumnResize: true,
//         // 列名
//         colHeaders: [
//             '测试字段',
//             '匹配模式',
//             '期望值',
//             '取反',
//             '上次执行结果',
//             '上次错误信息',
//         ],
//         // 为列设置默认值
//         dataSchema: {
//             test_field: '响应文本',
//             matching_rule: '包括',
//             value: '',
//             negater: false,
//             last_result: false,
//             last_failure_msg: '初次执行前默认失败',
//         },
//         // 设置列数据类型
//         columns: [
//             {
//                 data: 'test_field',
//                 type: 'dropdown',
//                 source: ['响应文本', '响应码', '响应头', '请求数据', '请求头']
//             },
//             {
//                 data: 'matching_rule',
//                 type: 'dropdown',
//                 source: ['包括', '匹配', '相等', '子字符串', 'XPath']
//             },
//             {
//                 data: 'value',
//                 renderer: renderValue,
//             },
//             {
//                 data: 'negater',
//                 type: 'checkbox',
//             },
//             {
//                 data: 'last_result',
//                 readOnly: true,
//                 renderer: renderLastResult,
//             },
//             {
//                 data: 'last_failure_msg',
//                 readOnly: true,
//                 // renderer: renderLastFailureMsg, // TODO 处理html字符串导致页面展示异常
//             },
//         ],
//         // 列宽比例
//         colWidths: [1.5, 1.5, 3, 1, 1.5, 5],
//         // 允许手工移动行或列
//         manualRowMove: true,
//         manualColumnMove: false,
//         // 右键菜单
//         contextMenu: ['row_above', 'row_below', '---------', 'remove_row', '---------', 'undo', 'redo', '---------', 'alignment', '---------', 'copy', 'cut'],
//         // 列是否支持过滤
//         filters: false,
//         // 下拉菜单
//         dropdownMenu: ['make_read_only', '---------', 'alignment'],
//         // 语言
//         language: 'zh-CN',
//         // 是否允许无效数据 默认 true
//         allowInvalid: false,
//         afterPaste: afterPasteHookForTableExpectation,
//         beforeChange: beforeChangeHookForTableExpectation,
//         afterLoadData: afterLoadDataHookForTableExpectation,
//     };
//
//     table_expectation = new Handsontable(container_table_expectation, option_table_expectation);
//
//     function renderLastResult(instance, td, row, col, prop, value, cellProperties) {
//         let lastResult = value.toString();  // value is bool
//         while (td.firstChild) {
//             td.removeChild(td.firstChild);
//         }
//         if (['true', 'false'].indexOf(lastResult) > -1) {
//             let lastResultElement = document.createElement('DIV');
//             lastResultElement.className = 'lastResult ' + lastResult.toLowerCase();
//             td.appendChild(lastResultElement);
//         } else {
//             let textNode = document.createTextNode(value === null ? '' : value);
//             td.appendChild(textNode);
//         }
//     }
//
//     function renderValue(instance, td, row, col, prop, value, cellProperties) {
//         let xpathSeparator = "|xpathSeparator|";
//         let matchingRule = instance.getDataAtCell(row, 1);
//         while (td.firstChild) {
//             td.removeChild(td.firstChild);  // TODO 会发生异常
//         }
//         if (matchingRule === "XPath"){
//             td.innerHTML = '<div class="input-group input-group-sm mt-1 mb-1">\n' +
//             '  <input type="text" class="form-control input-xpath h-75" placeholder="XPath表达式">\n' +
//             '  <input type="text" class="form-control input-expectation h-75" placeholder="期望值">\n' +
//             '</div>';
//
//             let xpathValue = value.split(xpathSeparator)[0];
//             let expectationValue = value.split(xpathSeparator)[1];
//
//             $($(td).find(".input-xpath")[0]).val(xpathValue);
//             $($(td).find(".input-expectation")[0]).val(expectationValue);
//
//
//             function updateValue(){
//                 let xpathValue = $($(td).find(".input-xpath")[0]).val();
//                 let expectationValue = $($(td).find(".input-expectation")[0]).val();
//                 instance.setDataAtCell(row, col, xpathValue + xpathSeparator + expectationValue)  // 会触发表格渲染  或许用loadData？
//             }
//
//             function onblurEvent(){
//                 updateValue();
//             }
//
//             function keydownEvent(e){
//                 if (e.keyCode === 13) {  // 回车键
//                     updateValue();
//                 }
//             }
//
//             // $($(td).find(".input-xpath")[0]).bind("input", updateValue);  // 每次输入触发input事件后表格都会渲染一次，光标需要重新选择
//             // $($(td).find(".input-expectation")[0]).bind("input", updateValue);
//             $($(td).find(".input-xpath")[0]).on("keydown", keydownEvent);
//             // $($(td).find(".input-xpath")[0]).blur(onblurEvent);
//             $($(td).find(".input-xpath")[0]).on("blur", onblurEvent);
//             $($(td).find(".input-expectation")[0]).on("keydown", keydownEvent);
//             // $($(td).find(".input-expectation")[0]).blur(onblurEvent);
//             $($(td).find(".input-expectation")[0]).on("blur", onblurEvent);
//         }else {
//             let textNode = document.createTextNode(value === null ? '' : value);
//             td.appendChild(textNode);
//         }
//     }
//
//     // 解决复制粘贴后checkBox中的值由布尔类型变为字符串的问题
//     function afterPasteHookForTableExpectation() {
//         let data = table_expectation.getSourceData();
//         for (let i = 0; i < data.length; ++i) {
//             let row = data[i];
//             if (row.negater === 'false'){
//                 row.negater = false;
//             }
//             if (row.negater === 'true'){
//                 row.negater = true;
//             }
//         }
//         table_expectation.loadData(data);
//     }
//
//     function beforeChangeHookForTableExpectation(changes, source){
//         // 暂时不知道为什么在afterPaste事件处理函数中无法将negater字段重置为布尔类型
//         // 因此又使用了beforeChange事件处理函数，在negater字段更新前判断要更新的值如果是字符串则重置为布尔类型
//         if (source === 'CopyPaste.paste'){
//             for (let i = 0; i < changes.length; i++) {  // changes 更新的数据
//                 let change = changes[i];  // change change[1]:字段名 change[2]:更新前的值(当前的值) change[3]:更新后的值
//                 if (change['1'] === 'negater'){
//                     if (change['3'] === 'false'){
//                         change['3'] = false;
//                     }
//                     if (change['3'] === 'true'){
//                         change['3'] = true;
//                     }
//                 }
//             }
//         }
//     }
//
//     // 数据加载完毕后隐藏spinner
//     function afterLoadDataHookForTableExpectation() {
//        $div_table_expectation_spinner.css('display', 'none');
//     }
// }
//
// // 支持案例页面上下分割
// function renderSplitter(minSize) {
//     Split(['#div-case-up', '#div-case-bottom'], {
//         // https://github.com/nathancahill/split/tree/master/packages/splitjs
//         sizes: [50, 50],
//         minSize: minSize,
//         // expandToMin: true,
//         gutterSize: 10,
//         direction: 'vertical',
//         cursor: 'row-resize',
//         gutter: function (index, direction, pairElement) {
//             const gutter = document.createElement('div');
//             gutter.className = `gutter gutter-${direction} div-split-gutter`;
//             return gutter
//         }
//         // direction: 'horizontal',
//     });
// }
//
// // ctrl+s保存测试案例数据
// function documentSaveCase(event) {
//     //可以判断是不是mac，如果是mac,ctrl变为花键
//     if (event.keyCode == 83 && (navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey)) {
//         event.preventDefault();  // 阻止元素事件的默认行为
//         saveCase();
//     }
// }
//
// // 用例保存
// function saveCase() {
// // 在各个case.js中实现
// }
//
// // 用例删除
// function deleteCase() {
//     let case_id = $btn_case_delete.data("case-id").toString();
//
//     Swal.fire({
//         title: '确定删除 案例' + case_id + ' 吗?',
//         text: '删除后将无法恢复!',
//         icon: 'warning',
//         showCancelButton: true,
//         confirmButtonColor: '#3085d6',
//         cancelButtonColor: '#d33',
//         confirmButtonText: '确定',
//         cancelButtonText: '取消',
//     }).then((result) => {
//         if (result.value) {
//             $.ajax({
//                 type: 'POST',
//                 url: '/ajax/case/delete',
//                 data: {
//                     case_id: case_id,
//                 },
//                 success: function (data, status, xhr) {
//                     if (data.error_no === 0){
//                         // message("删除案例成功", "success");
//                         Swal.fire({
//                             title: '删除!',
//                             text: '案例' + case_id + '已被删除.',
//                             icon: 'success',
//                         });
//                         alert_auto_redirect_close_timer(2000, '删除成功，跳转到新增页面', '/case/new')
//                     }else{
//                         message("删除案例失败: " + data.error_msg, "error");
//                     }
//                 },
//             });
//         }
//     });
// }
//
// // 案例删除提示框
// function alert_auto_redirect_close_timer(time, title, url) {
//     let timerInterval;
//     Swal.fire({
//         title: title,
//         html: '将在 <b></b> ms内跳转.',
//         timer: time,
//         timerProgressBar: true,
//         allowOutsideClick: false,
//         icon: 'success',
//         onBeforeOpen: () => {
//             Swal.showLoading();
//             timerInterval = setInterval(() => {
//                 const content = Swal.getContent();
//                 if (content) {
//                     const b = content.querySelector('b');
//                     if (b) {
//                         b.textContent = Swal.getTimerLeft();
//                     }
//                 }
//             }, 100)
//         },
//         onClose: () => {
//             clearInterval(timerInterval)
//         }
//     }).then((result) => {
//         // console.log(result);
//         /* Read more about handling dismissals below */
//         // if (result.dismiss === Swal.DismissReason.timer) {
//         //     console.log('I was closed by the timer')
//         // }
//         // 重定向到指定url
//         window.location.href = url;
//     })
// }
//
// // 用例执行
// function sendCase() {
//     let case_id = $btn_case_send.data("case-id").toString();
//     let case_type = $input_case_type.val();
//     console.log(case_type);
//     let url = '/ajax/case/' + case_type.toLowerCase() + '/execute';
//     // 每次发送前重置前台结果提示元素的样式
//     $btn_case_send.attr('disabled', '');
//     $div_spinner.css('display', '');
//     $btn_case_send_spinner.css('display', '');
//     switchAssertStyleToDefault();
//     $.ajax({
//         type: 'POST',
//         url: url,
//         data: {
//             case_id: case_id,
//         },
//         success: function (data, status, xhr) {
//             if (data.error_no === 0){
//                 message("请求发送成功", "success");
//                 // 前台展示应答和请求数据
//                 // $card_text_response_body.text(data.response_body);
//                 // $card_text_response_header.html(data.response_headers);
//                 // $card_text_request_body.html(data.request_body);
//                 // $card_text_request_header.html(data.request_headers);
//                 // request_header_default_data = JSON.stringify(data.request_headers);
//                 // request_body_defalut_data = JSON.stringify(data.request_body);
//                 // response_header_default_data = JSON.stringify(data.response_headers);
//                 // if (whatIsIt(data.response_body) === 'Object'){
//                 //     response_body_default_data = JSON.stringify(data.response_body);
//                 // 日志
//                 ace_log_editor.session.setValue(data.log);
//                 // 响应体
//                 if (isHtml(data.response_body)){
//                     response_body_default_data = data.response_body;
//                     ace_response_body_editor.session.setMode("ace/mode/html");
//                 }else{
//                     response_body_default_data = data.response_body;
//                     ace_response_body_editor.session.setMode("ace/mode/json");
//                 }
//                 request_header_default_data = data.request_headers;
//                 request_body_defalut_data = data.request_body;
//                 response_header_default_data = data.response_headers;
//                 ace_response_body_editor.session.setValue(response_body_default_data);  // 响应体
//                 ace_request_header_editor.session.setValue(request_header_default_data);  // 请求头
//                 ace_request_body_editor.session.setValue(request_body_defalut_data);  // 请求体
//                 ace_response_header_editor.session.setValue(response_header_default_data);  // 响应头
//                 switchRadioButtonToDefault();
//                 // 更新期望表格
//                 table_expectation.loadData(data.expectations);
//                 let has_expectations = false;
//                 if (data.expectations.length > 0) has_expectations = true;  // 判断是否有设置期望/断言
//                 // 根据期望结果进行前台展示提示信息
//                 if (data.assert_success){
//                     $div_assert_result_success_hint.css('display', '');
//                     switchExpectationResultToSuccess();
//                     switchPostprocessorResultToSuccess();
//                 }else{
//                     if (!data.expectations_result){  // 期望断言失败
//                         if (has_expectations){
//                             switchExpectationResultToFailure();
//                         }else{   // 未设置期望
//                             $div_expectation_not_set_hint.css('display', '');
//                         }
//                     }else{  // 期望断言成功
//                         switchExpectationResultToSuccess();
//                     }
//                     if (data.postprocessor_failure){  // 后处理断言失败
//                         switchPostprocessorResultToFailure(data.postprocessor_failure_message);
//                     }else{  // 后处理成功
//                         switchPostprocessorResultToSuccess();
//                     }
//                 }
//                 // 如果请求的应答头包含附件内容
//                 checkResponseHeaderHasAttachment(data.response_headers);
//             }else{
//                 // 日志
//                 ace_log_editor.session.setValue(data.log);
//                 message("请求发送失败: " + data.error_msg, "error");
//             }
//         },
//         complete: function (jqXHR, textStatus) {
//             $btn_case_send.removeAttr('disabled');
//             $btn_case_send_spinner.css('display', 'none');
//             $div_spinner.css('display', 'none');
//         }
//     });
// }
//
// // 代码美化以及恢复默认
// function beautifyRequestCode() {
//     let request_header_code = ace_request_header_editor.session.getValue();
//     let request_body_code = ace_request_body_editor.session.getValue();
//     ace_request_header_editor.session.setValue(js_beautify(request_header_code));
//     ace_request_body_editor.session.setValue(js_beautify(request_body_code));
// }
// function defaultRequestCode() {
//     ace_request_header_editor.session.setValue(request_header_default_data);
//     ace_request_body_editor.session.setValue(request_body_defalut_data);
// }
// function beautifyResponseCode() {
//     let response_header_code = ace_response_header_editor.session.getValue();
//     ace_response_header_editor.session.setValue(js_beautify(response_header_code));
//     let response_body_code = ace_response_body_editor.session.getValue();
//     if (isHtml(response_body_code)){
//         ace_response_body_editor.session.setMode("ace/mode/html");
//         ace_response_body_editor.session.setValue(html_beautify(response_body_code));
//     }else{
//         ace_response_body_editor.session.setMode("ace/mode/json");
//         ace_response_body_editor.session.setValue(js_beautify(response_body_code));
//     }
// }
// function defaultResponseCode() {
//     ace_response_header_editor.session.setValue(response_header_default_data);
//     ace_response_body_editor.session.setValue(response_body_default_data);
// }
// // 重置(默认/美化)Radio激活状态
// function switchRadioButtonToDefault() {
//     $radio_default_request_code.parent().addClass('active');
//     $radio_beautify_request_code.parent().removeClass('active');
//     $radio_default_response_code.parent().addClass('active');
//     $radio_beautify_response_code.parent().removeClass('active');
// }
//
// // 重置断言结果样式(包括期望断言和后处理脚本断言)
// function switchAssertStyleToDefault() {
//     $pills_expectation_tab.removeClass('success').removeClass('failure');   // tab 样式
//     $pills_postprocessor_script_tab.removeClass('success').removeClass('failure');  // tab 样式
//     $div_assert_result_success_hint.css('display', 'none');   // 结果提示div样式
//     $div_expectation_result_failure_hint.css('display', 'none');
//     $div_expectation_not_set_hint.css('display', 'none');
//     $div_postprocessor_result_failure_hint.css('display', 'none');
//     $div_postprocessor_result_card.removeClass('border-danger').removeClass('border-success').addClass('border-light');  // 后处理结果card样式
//     $badge_postprocessor_result_success.css('display', 'none');
//     $badge_postprocessor_result_failure.css('display', 'none');
//     $p_postprocessor_result_card_text.text('');  // 后处理失败信息
// }
// // 期望断言成功样式设置
// function switchExpectationResultToSuccess() {
//     $pills_expectation_tab.addClass('success');
// }
// // 后处理脚本断言成功样式设置
// function switchPostprocessorResultToSuccess() {
//     $pills_postprocessor_script_tab.addClass('success');
//     $div_postprocessor_result_card.removeClass('border-light').addClass('border-success');
//     $badge_postprocessor_result_success.css('display', '');
// }
// // 期望断言失败样式设置
// function switchExpectationResultToFailure() {
//     $pills_expectation_tab.addClass('failure');
//     $div_expectation_result_failure_hint.css('display', '');
// }
// // 后处理脚本断言失败样式设置
// function switchPostprocessorResultToFailure(postprocessor_failure_message) {
//     $pills_postprocessor_script_tab.addClass('failure');
//     $div_postprocessor_result_card.removeClass('border-light').addClass('border-danger');
//     $div_postprocessor_result_failure_hint.css('display', '');
//     $badge_postprocessor_result_failure.css('display', '');
//     $p_postprocessor_result_card_text.text(postprocessor_failure_message);
// }
//
// // 在ace editor编辑框内光标位置插入指定文本内容
// function scriptInsertText(event) {
//     let editor = event.data.editor;
//     let text = event.data.text;
//     editor.insert(text);
// }
//
// // 自动更新Top页面上的案例名信息
// function updateCaseName() {
//     let case_name = $input_case_name.val();
//     $wtd_div_case_name.text(case_name);
// }
// // 自动更新Top页面上的案例方法
// function updateCaseMethod() {
//     let case_method = $select_method.val();
//     $wtd_div_case_method.text(case_method);
// }
//
// // 检查应答头中包含附件内容
// function checkResponseHeaderHasAttachment(headers) {
//     let checkAttachementRegExp = /.*(attachment);.*filename=(.+)/;
//     headers = JSON.parse(headers);
//     for(let key in headers){
//         if('content-disposition' === key.toLowerCase()){
//             if(checkAttachementRegExp.test(headers[key])){  // 匹配到正则
//                 let fileName = checkAttachementRegExp.exec(headers[key])[2];
//                 $btn_save_response.data('fileName', fileName);
//                 $btn_save_response.attr('disabled', false);
//             }
//         }
//     }
// }
//
// // 保存应答内容
// function saveResponse() {
//     let fileName = $btn_save_response.data('fileName');
//     if(fileName === undefined || fileName === ''){
//         fileName = 'unknown'
//     }
//     download('/util/download/' + fileName);
// }

function getBaseCaseElement(case_id, case_type) {

    let element = new Object;
    element.dom = new Object;
    element.obj = new Object;

    // 组件中的对象
    element.obj.ace_request_header_editor = null;       // 请求头格式化编辑器
    element.obj.ace_request_body_editor = null;         // 请求体格式化编辑器
    element.obj.ace_response_header_editor = null;      // 应答头格式化编辑器
    element.obj.ace_response_body_editor = null;        // 应答体格式化编辑器
    element.obj.ace_preprocessor_script_editor = null;  // 预处理脚本格式化编辑器
    element.obj.ace_postprocessor_script_editor = null; // 后处理脚本格式化编辑器
    element.obj.ace_log_editor = null;                  // 日志展示
    element.obj.table_expectation = null;               // 期望数据表格
    element.obj.request_header_default_data = '';       // 请求头默认数据
    element.obj.request_body_defalut_data = '';         // 请求体默认数据
    element.obj.response_header_default_data = '';      // 应答头默认数据
    element.obj.response_body_default_data = '';        // 应答体默认数据

    // 案例页面元素
    element.dom.$input_case_name = $(`#input-case-name-${case_id}`);
    element.dom.$input_case_description = $(`#input-case-description-${case_id}`);
    element.dom.$select_method = $(`#select-method-${case_id}`);
    element.dom.$btn_case_delete = $(`#btn-case-delete-${case_id}`);
    element.dom.$btn_case_save = $(`#btn-case-save-${case_id}`);
    element.dom.$btn_case_send = $(`#btn-case-send-${case_id}`);
    element.dom.$btn_case_send_spinner = $(`#btn-case-send-spinner-${case_id}`);
    element.dom.$div_spinner = $(`#div-spinner-${case_id}`);

    element.dom.$pills_expectation_tab = $(`#pills-expectation-tab-${case_id}`);
    element.dom.$pills_postprocessor_script_tab = $(`#pills-postprocessor-script-tab-${case_id}`);
    element.dom.$div_table_expectation_spinner = $(`#div-table-expectation-spinner-${case_id}`);
    element.dom.$btn_save_response = $(`#btn-save-response-${case_id}`);
    element.dom.$radio_expectation_logic_and = $(`#radio-expectation-logic-and-${case_id}`);
    element.dom.$radio_expectation_logic_or = $(`#radio-expectation-logic-or-${case_id}`);
    element.dom.$radio_default_request_code = $(`#radio-default-request-code-${case_id}`);
    element.dom.$radio_beautify_request_code = $(`#radio-beautify-request-code-${case_id}`);
    element.dom.$radio_default_response_code = $(`#radio-default-response-code-${case_id}`);
    element.dom.$radio_beautify_response_code = $(`#radio-beautify-response-code-${case_id}`);
    element.dom.$div_postprocessor_result_card = $(`#div-postprocessor-result-card-${case_id}`);
    element.dom.$badge_postprocessor_result_success = $(`#badge-postprocessor-result-success-${case_id}`);
    element.dom.$badge_postprocessor_result_failure = $(`#badge-postprocessor-result-failure-${case_id}`);
    element.dom.$p_postprocessor_result_card_text = $(`#p-postprocessor-result-card-text-${case_id}`);
    element.dom.$div_assert_result_success_hint = $(`#div-assert-result-success-hint-${case_id}`);
    element.dom.$div_expectation_result_failure_hint = $(`#div-expectation-result-failure-hint-${case_id}`);
    element.dom.$div_expectation_not_set_hint = $(`#div-expectation-not-set-hint-${case_id}`);
    element.dom.$div_postprocessor_result_failure_hint = $(`#div-postprocessor-result-failure-hint-${case_id}`);
    element.dom.$button_ace_preprocessor_log = $(`#button-ace-preprocessor-log-${case_id}`);
    element.dom.$button_ace_preprocessor_set_variable = $(`#button-ace-preprocessor-set-variable-${case_id}`);
    element.dom.$button_ace_preprocessor_get_variable = $(`#button-ace-preprocessor-get-variable-${case_id}`);
    element.dom.$button_ace_postprocessor_log = $(`#button-ace-postprocessor-log-${case_id}`);
    element.dom.$button_ace_postprocessor_get_variable = $(`#button-ace-postprocessor-get-variable-${case_id}`);
    element.dom.$button_ace_postprocessor_set_variable= $(`#button-ace-postprocessor-set-variable-${case_id}`);
    element.dom.$button_ace_postprocessor_get_request_headers = $(`#button-ace-postprocessor-get-request-headers-${case_id}`);
    element.dom.$button_ace_postprocessor_get_request_body = $(`#button-ace-postprocessor-get-request-body-${case_id}`);
    element.dom.$button_ace_postprocessor_get_response_headers = $(`#button-ace-postprocessor-get-response-headers-${case_id}`);
    element.dom.$button_ace_postprocessor_get_response_body = $(`#button-ace-postprocessor-get-response-body-${case_id}`);
    element.dom.$button_ace_postprocessor_get_set_assert = $(`#button-ace-postprocessor-set-assert-${case_id}`);

    element.dom.$wtd_div_case_name =  $(`.case-name[data-case-id=${case_id}]`);
    element.dom.$wtd_div_case_method =  $(`.case-method[data-case-id=${case_id}]`);
    element.dom.$nav_badge_case_preprocess_script = $(`.badge-script[data-case-id=${case_id}][data-script-type='pre']`);
    element.dom.$nav_badge_case_postprocess_script = $(`.badge-script[data-case-id=${case_id}][data-script-type='post']`);

    // 初始化
    element.init = function(data_expectations){
        // 参数
        // data_expectations: 案例期望数据

        // 输入框格式化
        maskInput();
        // 渲染文本编辑器
        renderAceEditor();
        // 渲染期望表格
        renderExpectationTable(data_expectations);
        // 事件绑定
        eventBinding();
    };

    // 输入框格式化
    function maskInput () {
        let maskOption = {
            translation: {
                'Z': {
                    pattern: /./, optional: true
                }
            }
        };
        element.dom.$input_case_name.mask('Z'.repeat(200), maskOption);  // 限制长度为200
        element.dom.$input_case_description.mask('Z'.repeat(200), maskOption);
    }

    // 渲染文本编辑器
    function renderAceEditor () {
        // 请求头
        element.obj.ace_request_header_editor = ace.edit(`div-ace-request-header-${case_id}`);
        element.obj.ace_request_header_editor.setReadOnly(true);
        element.obj.ace_request_header_editor.setTheme("ace/theme/eclipse");
        element.obj.ace_request_header_editor.session.setMode("ace/mode/json");
        // 请求体
        element.obj.ace_request_body_editor = ace.edit(`div-ace-request-body-${case_id}`);
        element.obj.ace_request_body_editor.setReadOnly(true);
        element.obj.ace_request_body_editor.setTheme("ace/theme/eclipse");
        element.obj.ace_request_body_editor.session.setMode("ace/mode/json");
        // 应答头
        element.obj.ace_response_header_editor = ace.edit(`div-ace-response-header-${case_id}`);
        element.obj.ace_response_header_editor.setReadOnly(true);
        element.obj.ace_response_header_editor.setTheme("ace/theme/eclipse");
        element.obj.ace_response_header_editor.session.setMode("ace/mode/json");
        // 应答体
        element.obj.ace_response_body_editor = ace.edit(`div-ace-response-body-${case_id}`);
        element.obj.ace_response_body_editor.setReadOnly(true);
        element.obj.ace_response_body_editor.setTheme("ace/theme/eclipse");
        element.obj.ace_response_body_editor.session.setMode("ace/mode/html");
        // 预处理脚本
        element.obj.ace_preprocessor_script_editor = ace.edit(`div-ace-preprocessor-script-${case_id}`);
        element.obj.ace_preprocessor_script_editor.setTheme("ace/theme/eclipse");
        element.obj.ace_preprocessor_script_editor.session.setMode("ace/mode/python");
        // 后处理脚本
        element.obj.ace_postprocessor_script_editor = ace.edit(`div-ace-postprocessor-script-${case_id}`);
        element.obj.ace_postprocessor_script_editor.setTheme("ace/theme/eclipse");
        element.obj.ace_postprocessor_script_editor.session.setMode("ace/mode/python");
        // 日志
        element.obj.ace_log_editor = ace.edit(`div-ace-log-${case_id}`);
        element.obj.ace_log_editor.setTheme("ace/theme/log");
        element.obj.ace_log_editor.session.setMode("ace/mode/log");
    }

    // 渲染期望表格
    function renderExpectationTable(data_expectations) {
        // const container_table_expectation = document.getElementById(`table-expectation-${case_id}`);
        const option_table_expectation = {
            data: data_expectations,
            rowHeaders: true,
            // colHeaders: true,
            licenseKey: 'non-commercial-and-evaluation',
            // 表格宽度
            // width: '95vw',  // 不指定宽度使其自适应容器
            // 拉伸方式
            stretchH: 'all',
            // tab键自动换行切换
            autoWrapRow: true,
            height: '55vh',
            // 最大行数
            maxRows: 99,
            // 允许手工移动行或列
            manualRowResize: true,
            manualColumnResize: true,
            // 列名
            colHeaders: [
                '测试字段',
                '匹配模式',
                '期望值',
                '取反',
                '上次执行结果',
                '上次错误信息',
            ],
            // 为列设置默认值
            dataSchema: {
                test_field: '响应文本',
                matching_rule: '包括',
                value: '',
                negater: false,
                last_result: false,
                last_failure_msg: '初次执行前默认失败',
            },
            // 设置列数据类型
            columns: [
                {
                    data: 'test_field',
                    type: 'dropdown',
                    source: ['响应文本', '响应码', '响应头', '请求数据', '请求头']
                },
                {
                    data: 'matching_rule',
                    type: 'dropdown',
                    source: ['包括', '匹配', '相等', '子字符串', 'XPath']
                },
                {
                    data: 'value',
                    renderer: renderValue,
                },
                {
                    data: 'negater',
                    type: 'checkbox',
                },
                {
                    data: 'last_result',
                    readOnly: true,
                    renderer: renderLastResult,
                },
                {
                    data: 'last_failure_msg',
                    readOnly: true,
                    // renderer: renderLastFailureMsg, // TODO 处理html字符串导致页面展示异常
                },
            ],
            // 列宽比例
            colWidths: [1.5, 1.5, 3, 1, 1.5, 5],
            // 允许手工移动行或列
            manualRowMove: true,
            manualColumnMove: false,
            // 右键菜单
            contextMenu: ['row_above', 'row_below', '---------', 'remove_row', '---------', 'undo', 'redo', '---------', 'alignment', '---------', 'copy', 'cut'],
            // 列是否支持过滤
            filters: false,
            // 下拉菜单
            dropdownMenu: ['make_read_only', '---------', 'alignment'],
            // 语言
            language: 'zh-CN',
            // 是否允许无效数据 默认 true
            allowInvalid: false,
            afterPaste: afterPasteHookForTableExpectation,
            beforeChange: beforeChangeHookForTableExpectation,
            afterLoadData: afterLoadDataHookForTableExpectation,
        };
        // element.obj.table_expectation = new Handsontable(container_table_expectation, option_table_expectation);
        // 使用jqueryDom来创建ht实例，这样后面可以继续使用jqueryDom来获取ht实例，而不需要将ht实例存储到变量中
        let $container = $(`#table-expectation-${case_id}`);
        element.obj.table_expectation = $container.handsontable(option_table_expectation).handsontable('getInstance');
        // 渲染“上次执行结果”字段样式
        function renderLastResult(instance, td, row, col, prop, value, cellProperties) {
            let lastResult = value.toString();  // value is bool
            while (td.firstChild) {
                td.removeChild(td.firstChild);
            }
            if (['true', 'false'].indexOf(lastResult) > -1) {
                let lastResultElement = document.createElement('DIV');
                lastResultElement.className = 'lastResult ' + lastResult.toLowerCase();
                td.appendChild(lastResultElement);
            } else {
                let textNode = document.createTextNode(value === null ? '' : value);
                td.appendChild(textNode);
            }
        }
        // 渲染“期望值”字段样式
        function renderValue(instance, td, row, col, prop, value, cellProperties) {
            let xpathSeparator = "|xpathSeparator|";
            let matchingRule = instance.getDataAtCell(row, 1);
            while (td.firstChild) {
                td.removeChild(td.firstChild);  // TODO 会发生异常
            }
            if (matchingRule === "XPath"){
                td.innerHTML = '<div class="input-group input-group-sm mt-1 mb-1">\n' +
                '  <input type="text" class="form-control input-xpath h-75" placeholder="XPath表达式">\n' +
                '  <input type="text" class="form-control input-expectation h-75" placeholder="期望值">\n' +
                '</div>';

                let xpathValue = value.split(xpathSeparator)[0];
                let expectationValue = value.split(xpathSeparator)[1];

                $($(td).find(".input-xpath")[0]).val(xpathValue);
                $($(td).find(".input-expectation")[0]).val(expectationValue);

                function updateValue(){
                    let xpathValue = $($(td).find(".input-xpath")[0]).val();
                    let expectationValue = $($(td).find(".input-expectation")[0]).val();
                    instance.setDataAtCell(row, col, xpathValue + xpathSeparator + expectationValue)  // 会触发表格渲染  或许用loadData？
                }

                function onblurEvent(){
                    updateValue();
                }

                function keydownEvent(e){
                    if (e.keyCode === 13) {  // 回车键
                        updateValue();
                    }
                }

                // $($(td).find(".input-xpath")[0]).bind("input", updateValue);  // 每次输入触发input事件后表格都会渲染一次，光标需要重新选择
                // $($(td).find(".input-expectation")[0]).bind("input", updateValue);
                $($(td).find(".input-xpath")[0]).on("keydown", keydownEvent);
                // $($(td).find(".input-xpath")[0]).blur(onblurEvent);
                $($(td).find(".input-xpath")[0]).on("blur", onblurEvent);
                $($(td).find(".input-expectation")[0]).on("keydown", keydownEvent);
                // $($(td).find(".input-expectation")[0]).blur(onblurEvent);
                $($(td).find(".input-expectation")[0]).on("blur", onblurEvent);
            }else {
                let textNode = document.createTextNode(value === null ? '' : value);
                td.appendChild(textNode);
            }
        }

        // 解决复制粘贴后checkBox中的值由布尔类型变为字符串的问题
        function afterPasteHookForTableExpectation() {
            let data = element.obj.table_expectation.getSourceData();
            for (let i = 0; i < data.length; ++i) {
                let row = data[i];
                if (row.negater === 'false'){
                    row.negater = false;
                }
                if (row.negater === 'true'){
                    row.negater = true;
                }
            }
            element.obj.table_expectation.loadData(data);
        }

        function beforeChangeHookForTableExpectation(changes, source){
            // 暂时不知道为什么在afterPaste事件处理函数中无法将negater字段重置为布尔类型
            // 因此又使用了beforeChange事件处理函数，在negater字段更新前判断要更新的值如果是字符串则重置为布尔类型
            if (source === 'CopyPaste.paste'){
                for (let i = 0; i < changes.length; i++) {  // changes 更新的数据
                    let change = changes[i];  // change change[1]:字段名 change[2]:更新前的值(当前的值) change[3]:更新后的值
                    if (change['1'] === 'negater'){
                        if (change['3'] === 'false'){
                            change['3'] = false;
                        }
                        if (change['3'] === 'true'){
                            change['3'] = true;
                        }
                    }
                }
            }
        }

        // 数据加载完毕后隐藏spinner
        function afterLoadDataHookForTableExpectation() {
           element.dom.$div_table_expectation_spinner.css('display', 'none');
        }
    }

    // 事件绑定
    function eventBinding () {
        element.dom.$input_case_name.on("change keyup", updateCaseName);
        element.dom.$select_method.on("change", updateCaseMethod);  // 有些case没有select_method元素, jquery会忽略对不存在元素的操作, 且不会报错
        element.dom.$btn_case_save.bind("click", element.saveCase);
        element.dom.$btn_case_send.bind("click", sendCase);
        element.dom.$btn_save_response.bind("click", saveResponse);
        element.dom.$radio_beautify_request_code.bind("click", beautifyRequestCode);
        element.dom.$radio_default_request_code.bind("click", defaultRequestCode);
        element.dom.$radio_beautify_response_code.bind("click", beautifyResponseCode);
        element.dom.$radio_default_response_code.bind("click", defaultResponseCode);
        element.dom.$button_ace_preprocessor_log.bind("click", {'editor': element.obj.ace_preprocessor_script_editor, 'text': 'log.info(\'这里可以打印对象\')'}, scriptInsertText);
        element.dom.$button_ace_preprocessor_get_variable.bind("click", {'editor': element.obj.ace_preprocessor_script_editor, 'text': 'temp = vars.get(\'变量名\')'}, scriptInsertText);
        element.dom.$button_ace_preprocessor_set_variable.bind("click", {'editor': element.obj.ace_preprocessor_script_editor, 'text': 'vars[\'变量名\'] = 值'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_get_variable.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'temp = vars.get(\'变量名\')'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_log.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'log.info(\'这里可以打印对象\')'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_set_variable.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'vars[\'变量名\'] = 值'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_get_request_headers.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'temp = request_headers'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_get_request_body.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'temp = request_body'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_get_response_headers.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'temp = response_headers'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_get_response_body.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'temp = response_body'}, scriptInsertText);
        element.dom.$button_ace_postprocessor_get_set_assert.bind("click", {'editor': element.obj.ace_postprocessor_script_editor, 'text': 'if 1 != 0:\n    failure = True\n    failure_message = \'后处理断言失败\''}, scriptInsertText);
        element.obj.ace_preprocessor_script_editor.on('change', changePreProcessorScript);
        element.obj.ace_postprocessor_script_editor.on('change', changePostProcessorScript);
        element.dom.$pills_expectation_tab.on('shown.bs.tab', clickExpectationTab);

        // 自动更新Top页面上的案例名信息
        function updateCaseName() {
            let case_name = element.dom.$input_case_name.val();
            element.dom.$wtd_div_case_name.text(case_name);
        }
        // 自动更新Top页面上的案例方法
        function updateCaseMethod() {
            let case_method = element.dom.$select_method.val();
            element.dom.$wtd_div_case_method.text(case_method);
        }

        // 在ace editor编辑框内光标位置插入指定文本内容
        function scriptInsertText(event) {
            let editor = event.data.editor;
            let text = event.data.text;
            editor.insert(text);
        }

        // 保存应答内容
        function saveResponse() {
            let fileName = element.dom.$btn_save_response.data('fileName');
            if(fileName === undefined || fileName === ''){
                fileName = 'unknown'
            }
            download('/util/download/' + fileName);
        }

        // 预处理脚本更新
        function changePreProcessorScript() {
           let script = $.trim(element.obj.ace_preprocessor_script_editor.session.getValue());
           if(script === ''){
               element.dom.$nav_badge_case_preprocess_script.css('display', 'none');
           }else{
               element.dom.$nav_badge_case_preprocess_script.css('display', '');
           }
        }

        // 后处理脚本更新
        function changePostProcessorScript() {
            let script = $.trim(element.obj.ace_postprocessor_script_editor.session.getValue());
            if(script === ''){
                element.dom.$nav_badge_case_postprocess_script.css('display', 'none');
            }else{
                element.dom.$nav_badge_case_postprocess_script.css('display', '');
            }
        }

        // 点击期望tab页
        function clickExpectationTab() {
            // invisible状态下ht不可被渲染，因此在这里渲染
            $(`#table-expectation-${case_id}`).handsontable('getInstance').render();
        }

        // 用例执行
        function sendCase() {
            let url = '/ajax/case/' + case_type.toLowerCase() + '/execute';
            // 每次发送前重置前台结果提示元素的样式
            element.dom.$btn_case_send.attr('disabled', '');
            element.dom.$div_spinner.css('display', '');
            element.dom.$btn_case_send_spinner.css('display', '');
            switchAssertStyleToDefault();
            $.ajax({
                type: 'POST',
                url: url,
                data: {
                    case_id: case_id,
                },
                success: function (data, status, xhr) {
                    if (data.error_no === 0){
                        message("请求发送成功", "success");
                        // 前台展示应答和请求数据
                        // $card_text_response_body.text(data.response_body);
                        // $card_text_response_header.html(data.response_headers);
                        // $card_text_request_body.html(data.request_body);
                        // $card_text_request_header.html(data.request_headers);
                        // request_header_default_data = JSON.stringify(data.request_headers);
                        // request_body_defalut_data = JSON.stringify(data.request_body);
                        // response_header_default_data = JSON.stringify(data.response_headers);
                        // if (whatIsIt(data.response_body) === 'Object'){
                        //     response_body_default_data = JSON.stringify(data.response_body);
                        // 日志
                        element.obj.ace_log_editor.session.setValue(data.log);
                        // 响应体
                        if (isHtml(data.response_body)){
                            element.obj.response_body_default_data = data.response_body;
                            element.obj.ace_response_body_editor.session.setMode("ace/mode/html");
                        }else{
                            element.obj.response_body_default_data = data.response_body;
                            element.obj.ace_response_body_editor.session.setMode("ace/mode/json");
                        }
                        element.obj.request_header_default_data = data.request_headers;
                        element.obj.request_body_defalut_data = data.request_body;
                        element.obj.response_header_default_data = data.response_headers;
                        if(isHtml(element.obj.response_body_default_data)){
                            element.obj.ace_response_body_editor.session.setMode("ace/mode/html");
                            element.obj.ace_response_body_editor.session.setValue(html_beautify(element.obj.response_body_default_data));  // 响应体
                        }else{
                            element.obj.ace_response_body_editor.session.setMode("ace/mode/json");
                            element.obj.ace_response_body_editor.session.setValue(js_beautify(element.obj.response_body_default_data));  // 响应体
                        }
                        element.obj.ace_request_header_editor.session.setValue(js_beautify(element.obj.request_header_default_data));  // 请求头
                        element.obj.ace_request_body_editor.session.setValue(js_beautify(element.obj.request_body_defalut_data));  // 请求体
                        element.obj.ace_response_header_editor.session.setValue(js_beautify(element.obj.response_header_default_data));  // 响应头
                        switchRadioButtonToDefault();
                        // 更新期望表格
                        element.obj.table_expectation.loadData(data.expectations);
                        let has_expectations = false;
                        if (data.expectations.length > 0) has_expectations = true;  // 判断是否有设置期望/断言
                        // 根据期望结果进行前台展示提示信息
                        if (data.assert_success){
                            element.dom.$div_assert_result_success_hint.css('display', '');
                            switchExpectationResultToSuccess();
                            switchPostprocessorResultToSuccess();
                        }else{
                            if (!data.expectations_result){  // 期望断言失败
                                if (has_expectations){
                                    switchExpectationResultToFailure();
                                }else{   // 未设置期望
                                    element.dom.$div_expectation_not_set_hint.css('display', '');
                                }
                            }else{  // 期望断言成功
                                switchExpectationResultToSuccess();
                            }
                            if (data.postprocessor_failure){  // 后处理断言失败
                                switchPostprocessorResultToFailure(data.postprocessor_failure_message);
                            }else{  // 后处理成功
                                switchPostprocessorResultToSuccess();
                            }
                        }
                        // 如果请求的应答头包含附件内容
                        checkResponseHeaderHasAttachment(data.response_headers);
                    }else{
                        // 日志
                        element.obj.ace_log_editor.session.setValue(data.log);
                        message("请求发送失败: " + data.error_msg, "error");
                    }
                },
                complete: function (jqXHR, textStatus) {
                    element.dom.$btn_case_send.removeAttr('disabled');
                    element.dom.$btn_case_send_spinner.css('display', 'none');
                    element.dom.$div_spinner.css('display', 'none');
                }
            });
        }
    }

    // 代码美化以及恢复默认
    function beautifyRequestCode() {
        let request_header_code = element.obj.ace_request_header_editor.session.getValue();
        let request_body_code = element.obj.ace_request_body_editor.session.getValue();
        element.obj.ace_request_header_editor.session.setValue(js_beautify(request_header_code));
        element.obj.ace_request_body_editor.session.setValue(js_beautify(request_body_code));
    }
    function defaultRequestCode() {
        element.obj.ace_request_header_editor.session.setValue(element.obj.request_header_default_data);
        element.obj.ace_request_body_editor.session.setValue(element.obj.request_body_defalut_data);
    }
    function beautifyResponseCode() {
        let response_header_code = element.obj.ace_response_header_editor.session.getValue();
        element.obj.ace_response_header_editor.session.setValue(js_beautify(response_header_code));
        let response_body_code = element.obj.ace_response_body_editor.session.getValue();
        if (isHtml(response_body_code)){
            element.obj.ace_response_body_editor.session.setMode("ace/mode/html");
            element.obj.ace_response_body_editor.session.setValue(html_beautify(response_body_code));
        }else{
            element.obj.ace_response_body_editor.session.setMode("ace/mode/json");
            element.obj.ace_response_body_editor.session.setValue(js_beautify(response_body_code));
        }
    }
    function defaultResponseCode() {
        element.obj.ace_response_header_editor.session.setValue(element.obj.response_header_default_data);
        element.obj.ace_response_body_editor.session.setValue(element.obj.response_body_default_data);
    }
    // 重置(默认/美化)Radio激活状态
    function switchRadioButtonToDefault() {
        element.dom.$radio_default_request_code.parent().removeClass('active');
        element.dom.$radio_beautify_request_code.parent().addClass('active');
        element.dom.$radio_default_response_code.parent().removeClass('active');
        element.dom.$radio_beautify_response_code.parent().addClass('active');
    }
    // 重置断言结果样式(包括期望断言和后处理脚本断言)
    function switchAssertStyleToDefault() {
        element.dom.$pills_expectation_tab.removeClass('success').removeClass('failure');   // tab 样式
        element.dom.$pills_postprocessor_script_tab.removeClass('success').removeClass('failure');  // tab 样式
        element.dom.$div_assert_result_success_hint.css('display', 'none');   // 结果提示div样式
        element.dom.$div_expectation_result_failure_hint.css('display', 'none');
        element.dom.$div_expectation_not_set_hint.css('display', 'none');
        element.dom.$div_postprocessor_result_failure_hint.css('display', 'none');
        element.dom.$div_postprocessor_result_card.removeClass('border-danger').removeClass('border-success').addClass('border-light');  // 后处理结果card样式
        element.dom.$badge_postprocessor_result_success.css('display', 'none');
        element.dom.$badge_postprocessor_result_failure.css('display', 'none');
        element.dom.$p_postprocessor_result_card_text.text('');  // 后处理失败信息
    }
    // 期望断言成功样式设置
    function switchExpectationResultToSuccess() {
        element.dom.$pills_expectation_tab.addClass('success');
    }
    // 后处理脚本断言成功样式设置
    function switchPostprocessorResultToSuccess() {
        element.dom.$pills_postprocessor_script_tab.addClass('success');
        element.dom.$div_postprocessor_result_card.removeClass('border-light').addClass('border-success');
        element.dom.$badge_postprocessor_result_success.css('display', '');
    }
    // 期望断言失败样式设置
    function switchExpectationResultToFailure() {
        element.dom.$pills_expectation_tab.addClass('failure');
        element.dom.$div_expectation_result_failure_hint.css('display', '');
    }
    // 后处理脚本断言失败样式设置
    function switchPostprocessorResultToFailure(postprocessor_failure_message) {
        element.dom.$pills_postprocessor_script_tab.addClass('failure');
        element.dom.$div_postprocessor_result_card.removeClass('border-light').addClass('border-danger');
        element.dom.$div_postprocessor_result_failure_hint.css('display', '');
        element.dom.$badge_postprocessor_result_failure.css('display', '');
        element.dom.$p_postprocessor_result_card_text.text(postprocessor_failure_message);
    }

    // 检查应答头中包含附件内容
    function checkResponseHeaderHasAttachment(headers) {
        let checkAttachementRegExp = /.*(attachment);.*filename=(.+)/;
        headers = JSON.parse(headers);
        for(let key in headers){
            if('content-disposition' === key.toLowerCase()){
                if(checkAttachementRegExp.test(headers[key])){  // 匹配到正则
                    let fileName = checkAttachementRegExp.exec(headers[key])[2];
                    element.dom.$btn_save_response.data('fileName', fileName);
                    element.dom.$btn_save_response.attr('disabled', false);
                }
            }
        }
    }

    // 案例删除提示框
    function alert_auto_redirect_close_timer(time, title, url) {
        let timerInterval;
        Swal.fire({
            title: title,
            html: '将在 <b></b> ms内跳转.',
            timer: time,
            timerProgressBar: true,
            allowOutsideClick: false,
            icon: 'success',
            onBeforeOpen: () => {
                Swal.showLoading();
                timerInterval = setInterval(() => {
                    const content = Swal.getContent();
                    if (content) {
                        const b = content.querySelector('b');
                        if (b) {
                            b.textContent = Swal.getTimerLeft();
                        }
                    }
                }, 100)
            },
            onClose: () => {
                clearInterval(timerInterval)
            }
        }).then((result) => {
            // console.log(result);
            /* Read more about handling dismissals below */
            // if (result.dismiss === Swal.DismissReason.timer) {
            //     console.log('I was closed by the timer')
            // }
            // 重定向到指定url
            window.location.href = url;
        })
}


    // 供具体Case使用的方法(sendCase为公共方法，放在了eventBinding中定义)
    // 支持案例页面上下分割
    element.renderSplitter = function (minSize) {
        Split([`#div-case-up-${case_id}`, `#div-case-bottom-${case_id}`], {
            // https://github.com/nathancahill/split/tree/master/packages/splitjs
            sizes: [50, 50],
            minSize: minSize,
            // expandToMin: true,
            gutterSize: 10,
            direction: 'vertical',
            cursor: 'row-resize',
            gutter: function (index, direction, pairElement) {
                const gutter = document.createElement('div');
                gutter.className = `gutter gutter-${direction} div-split-gutter`;
                return gutter
            }
            // direction: 'horizontal',
        });
    };

    // 用例保存
    element.saveCase = function () {
        // 在各个case.js中实现
    };

    // 用例删除(前端已没有删除按钮)
    element.deleteCase = function () {
        Swal.fire({
            title: '确定删除 案例' + case_id + ' 吗?',
            text: '删除后将无法恢复!',
            icon: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#3085d6',
            cancelButtonColor: '#d33',
            confirmButtonText: '确定',
            cancelButtonText: '取消',
        }).then((result) => {
            if (result.value) {
                $.ajax({
                    type: 'POST',
                    url: '/ajax/case/delete',
                    data: {
                        case_id: case_id,
                    },
                    success: function (data, status, xhr) {
                        if (data.error_no === 0){
                            // message("删除案例成功", "success");
                            Swal.fire({
                                title: '删除!',
                                text: '案例' + case_id + '已被删除.',
                                icon: 'success',
                            });
                            alert_auto_redirect_close_timer(2000, '删除成功，跳转到新增页面', '/case/new')
                        }else{
                            message("删除案例失败: " + data.error_msg, "error");
                        }
                    },
                });
            }
        });
    };

    // 关键词查找
    element.mark = function (text) {
        // 匹配到则返回true
        let pat = new RegExp(text);
        let value = '';
        // 名称
        value = element.dom.$input_case_name.val();
        if (pat.test(value)) return true;
        // 注释
        value = element.dom.$input_case_description.val();
        if (pat.test(value)) return true;
        // // 请求头
        // value = element.obj.ace_request_header_editor.getValue();
        // if (pat.test(value)) return true;
        // // 请求体
        // value = element.obj.ace_request_body_editor.getValue();
        // if (pat.test(value)) return true;
        // // 响应头
        // value = element.obj.ace_response_header_editor.getValue();
        // if (pat.test(value)) return true;
        // // 响应体
        // value = element.obj.ace_response_body_editor.getValue();
        // if (pat.test(value)) return true;
        // 预处理脚本
        value = element.obj.ace_preprocessor_script_editor.getValue();
        if (pat.test(value)) return true;
        // 后处理脚本
        value = element.obj.ace_postprocessor_script_editor.getValue();
        if (pat.test(value)) return true;
        // // 日志
        // value = element.obj.ace_log_editor.getValue();
        // if (pat.test(value)) return true;
        // 期望表格
        let markFlag = false;
        value = element.obj.table_expectation.getSourceData();
        $.each(value, function (index, row) {
            $.each(row, function (column, data) {
                if (pat.test(data)){
                    markFlag = true;
                    return false;
                }
            });
        });
        if (markFlag) return true;
        // 未匹配到返回false
        return false;
    };

    return element;
}